﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Input;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Collections;
using System.Xml.Linq;
using System.Windows.Data;
using Twi.COMMON.HTTP;
using System.Data;
using System.Collections.Specialized;
using System.Windows.Shapes;

namespace Twi.COMMON.WPF
{
    public class CustomDataGrid : DataGrid
    {


        private MenuItem _item_copy;

        /// <summary>
        /// Excel全部页
        /// </summary>
        private MenuItem _item_export;
        /// <summary>
        /// Excel当前页
        /// </summary>
        private MenuItem _item_export_currentPage;

        /// <summary>
        /// Excel选中行
        /// </summary>
        private MenuItem _item_export_selecedItems;

        /// <summary>
        /// Word全部页
        /// </summary>
        private MenuItem _item_wordExport;
        /// <summary>
        /// Word当前页
        /// </summary>
        private MenuItem _item_wordExport_currentPage;

        /// <summary>
        /// Word选中行
        /// </summary>
        private MenuItem _item_wordExport_selectedItems;

        /// <summary>
        /// 列表自定义样式
        /// </summary>
        //private MenuItem _item_CustomStyle;

        public int ExportTotalNum = 0;

        Style styleDataGridColumnHeader = new Style(typeof(System.Windows.Controls.Primitives.DataGridColumnHeader));
        Style styleDataGridColumnHeader2 = new Style(typeof(System.Windows.Controls.Primitives.DataGridColumnHeader));
        public CustomDataGrid()
            : base()
        {

            this.CopyingRowClipboardContent += new EventHandler<DataGridRowClipboardEventArgs>(CustomDataGrid_CopyingRowClipboardContent);
            this.MouseRightButtonDown += new MouseButtonEventHandler(CustomDataGrid_MouseRightButtonDown);
            this.CustomDataGridContextMenu(); //右键上下文菜单
            this.Initialized += new EventHandler(CustomDataGrid_Initialized);

            this.Sorting += new DataGridSortingEventHandler(CustomDataGrid_Sorting);

            styleDataGridColumnHeader.Setters.Add(new Setter(System.Windows.Controls.Primitives.DataGridColumnHeader.FontWeightProperty, FontWeights.Bold));
            styleDataGridColumnHeader.Setters.Add(new Setter(System.Windows.Controls.Primitives.DataGridColumnHeader.HorizontalContentAlignmentProperty, HorizontalAlignment.Center));
            styleDataGridColumnHeader2.Setters.Add(new Setter(System.Windows.Controls.Primitives.DataGridColumnHeader.HorizontalContentAlignmentProperty, HorizontalAlignment.Center));

            _myCollectionView = (CollectionView)CollectionViewSource.GetDefaultView(this.Items);
            ((INotifyCollectionChanged)_myCollectionView).CollectionChanged += CustomDataGrid_CollectionChanged;

            this.Loaded += CustomDataGrid_Loaded;

            //         DataGridTemplateColumn template = new DataGridTemplateColumn();

            //         template.Header = "123";
            //         DataTemplate datatemplate = new DataTemplate();
            //         FrameworkElementFactory grid = new FrameworkElementFactory(typeof(Grid));

            //         datatemplate.VisualTree = grid;

            //         FrameworkElementFactory uStatus = new FrameworkElementFactory(typeof(UStatus));
            //         uStatus.SetValue(UStatus.TemplateColumnProperty, template);
            //         uStatus.SetBinding(UStatus.DataProperty, new Binding());
            //         grid.AppendChild(uStatus);
            //         template.CellTemplate = datatemplate;
            //this.Columns.Add(template);






        }

        public static Func<object, object> InitDataGrid;

        void CustomDataGrid_Loaded(object sender, RoutedEventArgs e)
        {
            _defaultSelectionMode = this.SelectionMode;

        }

        private CollectionView _myCollectionView = null;


        //protected override void OnMouseDown(MouseButtonEventArgs e)
        //{
        //    //防止出现在 [AddNew 或 EditItem 事务过程中不允许“Refresh”]
        //    if (IsUnderTabHeader(e.OriginalSource as DependencyObject)) 
        //        CommitTables(this);
        //    base.OnMouseDown(e);
        //}

        //private void CommitTables(DependencyObject control)
        //{
        //    if (control is DataGrid)
        //    {
        //        DataGrid grid = control as DataGrid;
        //        grid.CommitEdit(DataGridEditingUnit.Row, true);                
        //    }
        //    int childrenCount = VisualTreeHelper.GetChildrenCount(control);
        //    for (int childIndex = 0; childIndex < childrenCount; childIndex++)
        //        CommitTables(VisualTreeHelper.GetChild(control, childIndex));
        //}

        //private bool IsUnderTabHeader(DependencyObject control)
        //{
        //    if (control is TabItem) return true; 
        //    DependencyObject parent = VisualTreeHelper.GetParent(control);
        //    if (parent == null) 
        //        return false; 
        //    return IsUnderTabHeader(parent);
        //}


        public void BindAsTreeView(IEnumerable<XElement> source)
        {
            if (source.Count() > 0 && source.First() is RowXElement)
            {
                this.ItemsSource = source.ToArray();
            }
            else
            {
                this.ItemsSource = RowXElementHelper.GetFlattenedTreeViewItems(source).ToArray();
            }
        }




        #region 拖曳

        private DataGridSelectionMode _defaultSelectionMode = DataGridSelectionMode.Single;

        private bool _isDragMode = false;
        public bool IsDragMode
        {
            set
            {
                if (value)
                {
                    this.PreviewMouseLeftButtonDown += CustomDataGrid_PreviewMouseLeftButtonDown;
                    this.Drop += CustomDataGrid_Drop;

                    this.SelectionMode = DataGridSelectionMode.Single;
                    this.TreeNodeExpandable = false;
                    var selectedIndex = this.SelectedIndex;
                    this.Items.Refresh();
                    this.SelectedIndex = selectedIndex;
                    AllowDrop = true;
                }
                else
                {
                    this.PreviewMouseLeftButtonDown -= CustomDataGrid_PreviewMouseLeftButtonDown;
                    this.Drop -= CustomDataGrid_Drop;
                    this.SelectionMode = _defaultSelectionMode;
                    this.TreeNodeExpandable = true;
                    AllowDrop = false;
                }
                _isDragMode = value;
            }
            get { return _isDragMode; }
        }

        void CustomDataGrid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!_isDragMode)
            {
                return;
            }
            var draggedIndex = this.GetCurrentRowIndex(e.GetPosition);

            if (draggedIndex != -1)
            {
                DragDropEffects dragdropeffects = DragDropEffects.Move;
                DragDrop.DoDragDrop(this, draggedIndex, dragdropeffects);
            }
        }

        public Action AfterDragged = null;

        void CustomDataGrid_Drop(object sender, DragEventArgs e)
        {
            var draggedIndex = (int)e.Data.GetData("System.Int32");
            int targetIndex = this.GetCurrentRowIndex(e.GetPosition);
            if (targetIndex == draggedIndex || targetIndex == -1)
            {
                return;
            }

            XElement[] src = this.ItemsSource as XElement[];

            XElement[] dragBatch;
            if (!AsTreeView || (src[draggedIndex] as RowXElement).RowChildren == null)
            {
                dragBatch = new XElement[] { src[draggedIndex] as XElement };
            }
            else
            {
                dragBatch = (src[draggedIndex] as RowXElement).GetFlattenedChildrenAndSelf().ToArray();
            }

            if (draggedIndex < targetIndex)
            {
                //需要向上移动的条目
                var upwardBatch = src.Take(targetIndex + 1 +
                    (!AsTreeView ||
                    (src[targetIndex] as RowXElement).RowChildren == null ? 0
                    : (src[targetIndex] as RowXElement).GetFlattenedChildren().Count))
                    .Skip(draggedIndex + dragBatch.Length).ToArray();
                //下移开始的索引
                int downStartIndex = draggedIndex + upwardBatch.Length;

                //下移
                int i = downStartIndex;
                foreach (var x in dragBatch)
                {
                    src[i++] = x;
                }

                //上移
                int j = draggedIndex;
                foreach (var x in upwardBatch)
                {
                    src[j++] = x;
                }
            }
            else
            {
                //需要向下移动的条目
                var downwardBatch = src.Take(draggedIndex).Skip(targetIndex).ToArray();
                int upStartIndex = targetIndex;

                //上移
                int i = upStartIndex;
                foreach (var x in dragBatch)
                {
                    src[i++] = x;
                }

                //下移
                int j = targetIndex + dragBatch.Length;
                foreach (var x in downwardBatch)
                {
                    src[j++] = x;
                }
            }
            this.Items.Refresh();

            if (AfterDragged != null) { AfterDragged(); }
        }

        #endregion


        void CustomDataGrid_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (DefaultSelectedRowIndex > -1 && this.Items.Count > DefaultSelectedRowIndex)
            {
                this.SelectedIndex = DefaultSelectedRowIndex;
            }
        }

        bool _sortingAsc = true;
        void CustomDataGrid_Sorting(object sender, DataGridSortingEventArgs e)
        {
            if (AsTreeView)
            {
                e.Handled = true;
            }
            if (e.Column is DataGridTextColumn)
            {
                string sortExpression = ((e.Column as DataGridTextColumn).Binding as Binding).Path.Path.Split(new string[] { "Element[", "Attribute[", "].Value" }, StringSplitOptions.RemoveEmptyEntries)[0];

                decimal dec;
                //如果排序列的内容是数值型的话，按数值型来排序，而不是按字符窜来排序
                if (this.ItemsSource is XElement[])
                {
                    XElement xeFirstNotDecimal = (this.ItemsSource as XElement[]).Where(x => !decimal.TryParse(x.Element(sortExpression).GetValue(), out dec)).FirstOrDefault();
                    if (xeFirstNotDecimal == null)
                    {
                        if (_sortingAsc)
                        {
                            this.ItemsSource = (this.ItemsSource as XElement[]).OrderBy(x => decimal.Parse(x.Element(sortExpression).Value)).ToArray();
                        }
                        else
                        {
                            this.ItemsSource = (this.ItemsSource as XElement[]).OrderByDescending(x => decimal.Parse(x.Element(sortExpression).Value)).ToArray();
                        }
                        _sortingAsc = !_sortingAsc;
                        e.Handled = true;
                        return;
                    }
                }
                else if (this.ItemsSource is List<XElement>)
                {
                    XElement xeFirstNotDecimal = (this.ItemsSource as List<XElement>).Where(x => !decimal.TryParse(x.Element(sortExpression).GetValue(), out dec)).FirstOrDefault();
                    if (xeFirstNotDecimal == null)
                    {
                        if (_sortingAsc)
                        {
                            this.ItemsSource = (this.ItemsSource as List<XElement>).OrderBy(x => decimal.Parse(x.Element(sortExpression).Value)).ToList();
                        }
                        else
                        {
                            this.ItemsSource = (this.ItemsSource as List<XElement>).OrderByDescending(x => decimal.Parse(x.Element(sortExpression).Value)).ToList();
                        }
                        _sortingAsc = !_sortingAsc;
                        e.Handled = true;
                        return;
                    }
                }




            }
            e.Handled = false;
        }

        #region 剪贴板内容复制
        void CustomDataGrid_CopyingRowClipboardContent(object sender, DataGridRowClipboardEventArgs e)
        {
            for (int i = e.ClipboardRowContent.Count - 1; i >= 0; i--)
            {
                var x = e.ClipboardRowContent[i];
                if (x.Column == this.CurrentCell.Column)
                {

                }
                else
                {
                    e.ClipboardRowContent.Remove(x);
                }
            }
        }
        #endregion

        #region 模板列TextBox控件KeyUp事件

        public event RoutedEventHandler TextBoxLostFocus;

        public static readonly DependencyProperty TextBoxLostFocusEventTriggeredByProperty = DependencyProperty.Register("TextBoxLostFocusEventTriggeredBy"
            , typeof(string), typeof(CustomDataGrid));

        /// <summary>
        /// TemplateColumnTextBox事件由哪些绑定的列促发
        /// </summary>
        public string TextBoxLostFocusEventTriggeredBy
        {
            get { return GetValue(TextBoxLostFocusEventTriggeredByProperty).ToString(); }
            set { SetValue(TextBoxLostFocusEventTriggeredByProperty, value); }
        }


        #endregion


        #region CustomDataGrid 初始化
        void CustomDataGrid_Initialized(object sender, EventArgs e)
        {
            try
            {
                foreach (DataGridTemplateColumn c in this.Columns.Where(x => x.GetType() == typeof(DataGridTemplateColumn)).ToArray())
                {
                    //关于为什么不用c.CellTempalte.VisualTree
                    /* FrameworkTemplate.VisualTree property ... is mainly used when you programmatically create DataTemplate/ControlTemplate in code
                     * , When defining DataTemplate/ControlTemplate using XAML, this property will be null
                     * , because WPF uses another mechanism to instantiate and construct XAML generated templates. (emphasis added)
                     * */
                    var ctrl = c.CellTemplate.LoadContent();

                    #region 作废
                    //if (ctrl is DatePicker)
                    //{
                    //    DatePicker dp = ctrl as DatePicker;
                    //    FrameworkElementFactory fef = new FrameworkElementFactory(typeof(DatePicker));
                    //    BindingExpression bdexpr_Text = dp.GetBindingExpression(DatePicker.TextProperty);
                    //    if (bdexpr_Text != null) 
                    //    {
                    //        Binding bd_Text = bdexpr_Text.ParentBinding;
                    //        fef.SetBinding(DatePicker.TextProperty, bd_Text);
                    //        if (TextBoxLostFocus != null && TextBoxLostFocusEventTriggeredBy.Split(',').Contains(bd_Text.Path.Path))  //让客户端调用的自定义处理
                    //        {
                    //            fef.AddHandler(DatePicker.LostFocusEvent, TextBoxLostFocus);
                    //        }
                    //    }

                    //    BindingExpression bdexpr_IsEnabled = dp.GetBindingExpression(DatePicker.IsEnabledProperty);
                    //    if (bdexpr_IsEnabled != null)
                    //    {
                    //        Binding bd_IsEnabled = bdexpr_IsEnabled.ParentBinding;
                    //        if (bd_IsEnabled != null)
                    //        {
                    //            fef.SetBinding(DatePicker.IsEnabledProperty, bd_IsEnabled);
                    //        }
                    //    }
                    //    else
                    //    {
                    //        fef.SetValue(DatePicker.IsEnabledProperty, dp.IsEnabled);
                    //    }
                    //    fef.SetValue(DatePicker.NameProperty, dp.Name);
                    //    fef.SetValue(DatePicker.WidthProperty, dp.Width);
                    //    fef.SetValue(DatePicker.MinWidthProperty, dp.MinWidth);
                    //    fef.SetValue(DatePicker.MarginProperty, dp.Margin);

                    //    fef.AddHandler(DatePicker.SelectedDateChangedEvent, new SelectionChangedEventHandler(dp_SelectedDateChanged));


                    //    DataTemplate cellTemplate1 = new DataTemplate();
                    //    cellTemplate1.VisualTree = fef;
                    //    c.CellTemplate = cellTemplate1;


                    //}
                    //else
                    #endregion

                    if (ctrl is NumericTextBox)
                    {
                        #region NumericTextBox
                        NumericTextBox txt = ctrl as NumericTextBox;
                        FrameworkElementFactory fef = new FrameworkElementFactory(typeof(NumericTextBox));
                        BindingExpression bdexpr_Text = txt.GetBindingExpression(NumericTextBox.TextProperty);
                        if (bdexpr_Text != null)
                        {
                            Binding bd_Text = bdexpr_Text.ParentBinding;
                            fef.SetBinding(NumericTextBox.TextProperty, bd_Text);
                            if (TextBoxLostFocus != null && TextBoxLostFocusEventTriggeredBy.Split(',').Contains(bd_Text.Path.Path))  //让客户端调用的自定义处理
                            {
                                fef.AddHandler(NumericTextBox.LostFocusEvent, TextBoxLostFocus);
                            }
                        }

                        BindingExpression bdexpr_IsReadOnly = (ctrl as NumericTextBox).GetBindingExpression(NumericTextBox.IsReadOnlyProperty);
                        if (bdexpr_IsReadOnly != null)
                        {
                            Binding bd_IsReadOnly = bdexpr_IsReadOnly.ParentBinding;
                            if (bd_IsReadOnly != null)
                            {
                                fef.SetBinding(NumericTextBox.IsReadOnlyProperty, bd_IsReadOnly);
                            }
                        }
                        else
                        {
                            fef.SetValue(NumericTextBox.IsReadOnlyProperty, txt.IsReadOnly);
                        }
                        fef.SetValue(NumericTextBox.NameProperty, txt.Name);
                        fef.SetValue(NumericTextBox.WidthProperty, txt.Width);
                        fef.SetValue(NumericTextBox.MinWidthProperty, txt.MinWidth);
                        fef.SetValue(NumericTextBox.MarginProperty, txt.Margin);
                        fef.SetValue(NumericTextBox.DataTypePropery, txt.DataType);
                        fef.SetValue(NumericTextBox.AcceptsReturnProperty, txt.AcceptsReturn);
                        fef.AddHandler(NumericTextBox.TextChangedEvent, new TextChangedEventHandler(TextBox_TextChanged));
                        fef.AddHandler(NumericTextBox.SelectionChangedEvent, new RoutedEventHandler(TextBox_SelectionChanged));
                        fef.AddHandler(NumericTextBox.PreviewKeyDownEvent, new KeyEventHandler(TextBox_PreviewKeyDown));


                        DataTemplate cellTemplate1 = new DataTemplate();
                        cellTemplate1.VisualTree = fef;
                        c.CellTemplate = cellTemplate1;
                        #endregion
                    }
                    else if (ctrl is TextBox)
                    {
                        #region TextBox
                        TextBox txt = ctrl as TextBox;
                        FrameworkElementFactory fef = new FrameworkElementFactory(typeof(TextBox));
                        BindingExpression bdexpr_Text = txt.GetBindingExpression(TextBox.TextProperty);
                        if (bdexpr_Text != null)
                        {
                            Binding bd_Text = bdexpr_Text.ParentBinding;
                            fef.SetBinding(TextBox.TextProperty, bd_Text);
                            if (TextBoxLostFocus != null && TextBoxLostFocusEventTriggeredBy.Split(',').Contains(bd_Text.Path.Path))  //让客户端调用的自定义处理
                            {
                                fef.AddHandler(TextBox.LostFocusEvent, TextBoxLostFocus);
                            }
                        }

                        BindingExpression bdexpr_IsReadOnly = txt.GetBindingExpression(TextBox.IsReadOnlyProperty);
                        if (bdexpr_IsReadOnly != null)
                        {
                            Binding bd_IsReadOnly = bdexpr_IsReadOnly.ParentBinding;
                            if (bd_IsReadOnly != null)
                            {
                                fef.SetBinding(TextBox.IsReadOnlyProperty, bd_IsReadOnly);
                            }
                        }
                        else
                        {
                            fef.SetValue(TextBox.IsReadOnlyProperty, txt.IsReadOnly);
                        }
                        BindingExpression bdexpr_IsEnabled = txt.GetBindingExpression(TextBox.IsEnabledProperty);
                        if (bdexpr_IsEnabled != null)
                        {
                            Binding bd_IsEnabled = bdexpr_IsEnabled.ParentBinding;
                            if (bd_IsEnabled != null)
                            {
                                fef.SetBinding(TextBox.IsEnabledProperty, bd_IsEnabled);
                            }
                        }
                        else
                        {
                            fef.SetValue(TextBox.IsEnabledProperty, txt.IsEnabled);
                        }
                        fef.SetValue(TextBox.NameProperty, txt.Name);
                        fef.SetValue(TextBox.WidthProperty, txt.Width);
                        fef.SetValue(TextBox.MinWidthProperty, txt.MinWidth);
                        fef.SetValue(TextBox.MarginProperty, txt.Margin);
                        fef.SetValue(TextBox.AcceptsReturnProperty, txt.AcceptsReturn);
                        fef.AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(TextBox_TextChanged));
                        fef.AddHandler(TextBox.SelectionChangedEvent, new RoutedEventHandler(TextBox_SelectionChanged));
                        fef.AddHandler(TextBox.PreviewKeyDownEvent, new KeyEventHandler(TextBox_PreviewKeyDown));
                        fef.AddHandler(TextBox.PreviewMouseDoubleClickEvent, new MouseButtonEventHandler(TextBox_PreviewMouseDoubleClick));

                        DataTemplate cellTemplate1 = new DataTemplate();
                        cellTemplate1.VisualTree = fef;
                        c.CellTemplate = cellTemplate1;
                        #endregion
                    }
                    else if (ctrl is CheckBox)
                    {
                        CheckBox chk = ctrl as CheckBox;
                        FrameworkElementFactory fef = new FrameworkElementFactory(typeof(CheckBox));
                        fef.SetBinding(CheckBox.IsCheckedProperty, (ctrl as CheckBox).GetBindingExpression(CheckBox.IsCheckedProperty).ParentBinding);


                        BindingExpression bdexpr = (ctrl as CheckBox).GetBindingExpression(CheckBox.IsEnabledProperty);
                        if (bdexpr != null)
                        {
                            Binding bd_IsEnabled = bdexpr.ParentBinding;
                            if (bd_IsEnabled != null)
                            {
                                fef.SetBinding(CheckBox.IsEnabledProperty, bd_IsEnabled);
                            }
                        }

                        fef.SetValue(CheckBox.WidthProperty, chk.Width);
                        fef.SetValue(CheckBox.MinWidthProperty, chk.MinWidth);
                        fef.SetValue(CheckBox.MarginProperty, chk.Margin);
                        fef.SetValue(CheckBox.HorizontalAlignmentProperty, chk.HorizontalAlignment);
                        fef.AddHandler(CheckBox.ClickEvent, new RoutedEventHandler(CheckBox_Clicked));

                        DataTemplate cellTemplate1 = new DataTemplate();
                        cellTemplate1.VisualTree = fef;
                        c.CellTemplate = cellTemplate1;
                    }
                }
                InitialCustomDataGrid(); //初始化DataGrid列
            }
            catch
            {

            }
        }



        void dp_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
        {
            var dp = sender as System.Windows.Controls.DatePicker;
            if (dp.GetBindingExpression(System.Windows.Controls.DatePicker.SelectedDateProperty) != null)
            {
                dp.GetBindingExpression(System.Windows.Controls.DatePicker.SelectedDateProperty).UpdateSource();
            }
        }
        #endregion
        public void ClearColumn()
        {
            try
            {
                this.Columns.Clear();
            }
            catch { }
        }
        #region 初始化DataGrid列
        public void InitialCustomDataGrid()
        {
            try
            {
                if (this.UIPartCode == "" || this.UIPartCode == null || Config.ServerAddress() == null)
                    return;
                List<XElement> gridColumnsList = this.GetCustomGridColumns();  //自定义列表
                if (gridColumnsList.Count == 0)
                    gridColumnsList = this.GetGridColumns();    //全局

                List<DataGridColumn> exsitsColumnList = this.Columns.ToList();
                foreach (DataGridColumn dataGridColumn in exsitsColumnList)
                {
                    if (dataGridColumn.GetType() != typeof(DataGridTemplateColumn))
                    {
                        this.Columns.Remove(dataGridColumn);
                    }
                }
                if (InitDataGrid != null)
                {
                    InitDataGrid(this);
                }
                foreach (XElement xeItem in gridColumnsList)
                {
                    bool isReadOnly = xeItem.Element("IsReadOnly").GetValue<int>(1) == 1 ? true : false;
                    int width = xeItem.Element("Width").GetValue<int>(0);

                    if (xeItem.Element("ColumnType").GetValue<int>(0) == 1 && xeItem.Element("Visibility").GetValue<int>(0) == 0) //普通列并且是显示的列
                    {
                        Binding binding = new Binding(xeItem.Element("Binding").GetValue());
                        if (!isReadOnly)
                        {
                            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        }
                        SetBindingConverter(binding, xeItem.Element("BindingConverter").GetValue());  //绑定转换对象
                        if (xeItem.Element("ConverterParameter").GetValue() != "")
                            binding.ConverterParameter = xeItem.Element("ConverterParameter").GetValue(); //绑定参数

                        this.Columns.Add(new DataGridTextColumn()
                        {
                            Header = xeItem.Element("Header").GetValue(),
                            Width = width == 0 ? DataGridLength.Auto : new DataGridLength(width),
                            Binding = binding,
                            DisplayIndex = this.Columns.Count,
                            Visibility = (System.Windows.Visibility)xeItem.Element("Visibility").GetValue<int>(0),
                            IsReadOnly = isReadOnly,
                            //HeaderStyle = isReadOnly ? styleDataGridColumnHeader2 : styleDataGridColumnHeader,
                        });
                    }
                    else if (xeItem.Element("ColumnType").GetValue<int>(0) == 2) //界面已定义列
                    {
                        foreach (DataGridColumn dataGridColumn in this.Columns)
                        {
                            if (dataGridColumn.Header.ToString() == xeItem.Element("CriterionHeader").GetValue())
                            {
                                dataGridColumn.Header = xeItem.Element("Header").GetValue();
                                dataGridColumn.Width = width == 0 ? DataGridLength.Auto : new DataGridLength(width);
                                dataGridColumn.DisplayIndex = this.Columns.Count - 1;
                                dataGridColumn.Visibility = (System.Windows.Visibility)xeItem.Element("Visibility").GetValue<int>(0);
                                dataGridColumn.IsReadOnly = isReadOnly;
                                //dataGridColumn.HeaderStyle = styleDataGridColumnHeader;
                            }
                        }
                    }
                }


            }
            catch (Exception ex)
            {
                ErrorInfo er = new ErrorInfo("初始化DataGrid列失败", ex.Message);
                er.Show();
            }
        }
        public void SaveCustomGridColumn()
        {
            try
            {
                List<XElement> columnList = new List<XElement>();
                List<XElement> xeGridColumnsList = this.GetGridColumns(); //全局定义UI列表列

                if (xeGridColumnsList == null)
                    return;

                #region 自定义列表样式绑定
                int tempDisplayIndex = 199;  //用于没有显示出来的列序号排在后面
                foreach (XElement xeTempColumn in xeGridColumnsList.Where(x => x.Element("Visibility").GetValue<int>(0) == 0))
                {
                    DataGridColumn dgColumn = this.Columns.FirstOrDefault(x => x.Visibility == System.Windows.Visibility.Visible && x.Header.ToString() == xeTempColumn.Element("Header").GetValue());
                    int isVisibility = 2;
                    double width = xeTempColumn.Element("Width").GetValue<double>(10);
                    int displayIndex = tempDisplayIndex;
                    if (dgColumn != null)
                    {
                        isVisibility = 0;
                        width = dgColumn.Width.Value;
                        displayIndex = dgColumn.DisplayIndex;
                    }
                    else
                    {
                        tempDisplayIndex++;
                    }

                    XElement xeColumn = new XElement("frm_CustomGridColumn"
                            , new XElement("Width", width)
                            , new XElement("Visibility", isVisibility)
                            , new XElement("DisplayIndex", displayIndex)
                        //, new XElement("UserID", Login.UserLogin.CurrentUser.UserID)暂时不用，个人不能配显示列
                            , new XElement("UIPartCode", this.UIPartCode)
                            , xeTempColumn.Element("ColumnID"));
                    columnList.Add(xeColumn);

                    //using (var res = "CustomGridColumns/Create".HttpPost(columnList))
                    //{
                    //    ProcessRequest.Process(res, (ResponseMessageInfo resInfo) =>
                    //    {
                    //    });
                    //}
                }
                #endregion
            }
            catch (Exception ex)
            {
                ErrorInfo er = new ErrorInfo("保存自定义列表样式失败：", ex.Message);
                er.Show();
            }
        }
        /// <summary>
        /// 设置绑定转换
        /// </summary>
        /// <param name="binding"></param>
        /// <param name="bindingConverter"></param>
        private void SetBindingConverter(Binding binding, string bindingConverter)
        {
            switch (bindingConverter)
            {
                case "DateTimeConverter":
                    binding.Converter = new DateTimeConverter();
                    break;
                case "CommonConverter":
                    binding.Converter = new CommonConverter();
                    break;
                case "NodeConverter":
                    binding.Converter = new NodeConverter();
                    break;
                default:
                    break;
            }
        }
        #endregion

        #region 鼠标右键事件
        void CustomDataGrid_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (this.SelectedCells.Count == 0)
            {
                _item_copy.IsEnabled = false;
            }
            else
            {
                _item_copy.IsEnabled = true;
            }

            if (this.ContextMenu == null)
            {
                this.ContextMenu = new ContextMenu();
            }

            if (1 == 2)//ExportIsVisible,暂时右键菜单不加
            {
                if (_item_export_currentPage == null && ScrollbarPaging == false) //滚动分页的就不要导出当前页了
                {
                    _item_export_currentPage = new MenuItem();
                    _item_export_currentPage.Header = "导出到Excel（当前页）";
                    _item_export_currentPage.Click += new RoutedEventHandler(_item_export_currentPage_Click);
                    this.ContextMenu.Items.Add(_item_export_currentPage);
                }
                if (_item_export_selecedItems == null)
                {
                    _item_export_selecedItems = new MenuItem();
                    _item_export_selecedItems.Header = "导出到Excel（选中项）";
                    _item_export_selecedItems.Click += _item_export_selecedItems_Click;
                    this.ContextMenu.Items.Add(_item_export_selecedItems);
                }
                if (_item_export == null)
                {
                    _item_export = new MenuItem();
                    _item_export.Header = "导出到Excel（全部记录）";
                    _item_export.Click += new System.Windows.RoutedEventHandler(item_export_Click);
                    this.ContextMenu.Items.Add(_item_export);
                }

                if (_item_wordExport_currentPage == null && ScrollbarPaging == false) //滚动分页的就不要导出当前页了
                {
                    _item_wordExport_currentPage = new MenuItem();
                    _item_wordExport_currentPage.Header = "导出到Word（当前页）";
                    _item_wordExport_currentPage.Click += new RoutedEventHandler(_item_wordExport_currentPage_Click);
                    this.ContextMenu.Items.Add(_item_wordExport_currentPage);
                }
                if (this._item_wordExport_selectedItems == null)
                {
                    _item_wordExport_selectedItems = new MenuItem();
                    _item_wordExport_selectedItems.Header = "导出到Word（选中项）";
                    _item_wordExport_selectedItems.Click += _item_wordExport_selectedItems_Click;
                    this.ContextMenu.Items.Add(_item_wordExport_selectedItems);
                }
                if (_item_wordExport == null)
                {
                    _item_wordExport = new MenuItem();
                    _item_wordExport.Header = "导出到Word（全部记录）";
                    _item_wordExport.Click += new System.Windows.RoutedEventHandler(item_wordExport_Click);
                    this.ContextMenu.Items.Add(_item_wordExport);
                }

            }
            //if (_item_CustomStyle == null && this.UIPartCode != "" && IsCanCustom)
            //{
            //    Separator separator1 = new Separator();
            //    this.ContextMenu.Items.Add(separator1);

            //    _item_CustomStyle = new MenuItem();
            //    _item_CustomStyle.Header = "列表自定义";
            //    _item_CustomStyle.Click += new RoutedEventHandler(_item_CustomStyle_Click);
            //    this.ContextMenu.Items.Add(_item_CustomStyle);
            //}

            this.ContextMenu.IsOpen = true;
        }




        #endregion

        #region 右键上下文菜单


        private void CustomDataGridContextMenu()
        {
            _item_copy = new MenuItem();
            _item_copy.Header = "复制单元格内容";
            _item_copy.Click += new System.Windows.RoutedEventHandler(item_Click);
            if (this.ContextMenu == null)
            {
                this.ContextMenu = new ContextMenu();
            }
            this.ContextMenu.Items.Add(_item_copy);
        }


        #region 复制功能
        void item_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            int rowIndex = this.Items.IndexOf(this.CurrentItem);
            int columnIndex = this.Columns.IndexOf(this.CurrentColumn);
            if (rowIndex == -1 || columnIndex == -1) //某些操作可能会出现
            {
                return;
            }
            var content = GetCell(rowIndex, columnIndex).Content;
            if (content is TextBlock)
            {
                //防止未知异常
                try
                {
                    Clipboard.SetText((content as TextBlock).Text);
                }
                catch { }
            }
            else if (content is ContentPresenter)
            {
                var contentPresenter = content as ContentPresenter;
                var dataTemplate = contentPresenter.ContentTemplate;
                var tbDisplay = dataTemplate.FindName("TbDisplay", contentPresenter);
                if (tbDisplay != null && tbDisplay is TextBlock)
                {
                    //防止未知异常
                    try
                    {
                        Clipboard.SetText((tbDisplay as TextBlock).Text);
                    }
                    catch { }
                }
            }
        }
        #endregion

        void _item_export_selecedItems_Click(object sender, RoutedEventArgs e)
        {
            if (this.SelectedItems.Count > 0)
            {
                ExportExcel(this.SelectedItems.OfType<XElement>().ToList(), GetColumns());
            }
        }

        void _item_wordExport_selectedItems_Click(object sender, RoutedEventArgs e)
        {
            if (this.SelectedItems.Count > 0)
            {
                ExportWord(this.SelectedItems.OfType<XElement>().ToList(), GetColumns());
            }
        }


        #region Excel导出全部
        void item_export_Click(object sender, System.Windows.RoutedEventArgs e)
        {

            if (!Twi.COMMON.WPF.Tools.GAffirmOKCancel(GMessageInfo.确定要导出全部记录)) { return; }
            Export(ExportExcel, false);
        }
        #endregion
        #region Excel导出当前页
        void _item_export_currentPage_Click(object sender, RoutedEventArgs e)
        {
            Export(ExportExcel, true);
        }
        #endregion

        #region Word导出全部
        void item_wordExport_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (!Twi.COMMON.WPF.Tools.GAffirmOKCancel(GMessageInfo.确定要导出全部记录)) { return; }
            Export(ExportWord, false);
        }
        #endregion
        #region Word导出当前页
        void _item_wordExport_currentPage_Click(object sender, RoutedEventArgs e)
        {
            Export(ExportWord, true);
        }
        #endregion

        #region 列表样式用户自定义
        /// <summary>
        /// 列表样式用户自定义
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _item_CustomStyle_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                CustomDataGrid_Style customDataGrid_Style = new CustomDataGrid_Style();

                List<XElement> columnList = new List<XElement>();
                List<XElement> xeGridColumnsList = this.GetGridColumns(); //全局定义UI列表列

                if (xeGridColumnsList == null)
                    return;

                #region 自定义列表样式绑定
                int tempDisplayIndex = 199;  //用于没有显示出来的列序号排在后面
                foreach (XElement xeTempColumn in xeGridColumnsList.Where(x => x.Element("Visibility").GetValue<int>(0) == 0))
                {
                    DataGridColumn dgColumn = this.Columns.FirstOrDefault(x => x.Visibility == System.Windows.Visibility.Visible && x.Header.ToString() == xeTempColumn.Element("Header").GetValue());
                    int isVisibility = 1;
                    double width = xeTempColumn.Element("Width").GetValue<double>(10);
                    int displayIndex = tempDisplayIndex;
                    if (dgColumn != null)
                    {
                        isVisibility = 0;
                        width = dgColumn.Width.Value;
                        displayIndex = dgColumn.DisplayIndex;
                    }
                    else
                    {
                        tempDisplayIndex++;
                    }

                    XElement xeColumn = new XElement("frm_CustomGridColumn"
                            , xeTempColumn.Element("Header")
                            , new XElement("Width", width)
                            , new XElement("Visibility", isVisibility)
                            , new XElement("DisplayIndex", displayIndex));
                    columnList.Add(xeColumn);
                }
                customDataGrid_Style.DgCustomColumns.ItemsSource = columnList.OrderBy(x => x.Element("DisplayIndex").GetValue<int>(0)).ToArray();
                #endregion

                customDataGrid_Style.ShowDialog();

                bool isOK = false;
                #region 保存自定义列表样式
                if (customDataGrid_Style.DialogResult.Value)
                {
                    List<XElement> xeCustomColumns = customDataGrid_Style.DgCustomColumns.Items.OfType<XElement>().ToList();
                    foreach (XElement xeItem in xeCustomColumns)
                    {
                        xeItem.Element("Visibility").SetValue(xeItem.Element("Visibility").GetValue(0) == 1 ? 2 : 0);
                        //xeItem.Add(new XElement("UserID", Login.UserLogin.CurrentUser.UserID));
                        xeItem.Add(new XElement("UIPartCode", this.UIPartCode));

                        XElement xeTempItem = xeGridColumnsList.FirstOrDefault(x => x.Element("Header").Value == xeItem.Element("Header").Value);
                        xeItem.Add(xeTempItem != null ? xeTempItem.Element("ColumnID") : new XElement("ColumnID", 0));
                    }

                    using (var res = "CustomGridColumns/Create".HttpPost(xeCustomColumns))
                    {
                        ProcessRequest.Process(res, (ResponseMessageInfo resInfo) =>
                        {
                            isOK = true;
                        });
                    }
                }
                #endregion

                if (isOK)
                {
                    InitialCustomDataGrid();
                    this.UpdateLayout();
                    //MessageBox.Show("自定义样式已保存！", "系统提示");
                }
            }
            catch (Exception ex)
            {
                ErrorInfo er = new ErrorInfo("自定义样式失败：", ex.Message);
                er.Show();
            }

        }
        #endregion

        #endregion


        #region GetVisualChild

        public T GetVisualChild<T>(Visual parent) where T : Visual
        {
            T child = default(T);

            int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < numVisuals; i++)
            {
                Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
                child = v as T;
                if (child == null)
                {
                    child = GetVisualChild<T>(v);
                }
                if (child != null)
                {
                    break;
                }
            }

            return child;
        }

        #endregion GetVisualChild

        #region GetCell

        public DataGridCell GetCell(int row, int column)
        {
            DataGridRow rowContainer = GetRow(row);
            if (rowContainer != null)
            {
                DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);

                // try to get the cell but it may possibly be virtualized
                DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
                if (cell == null)
                {
                    // now try to bring into view and retreive the cell
                    this.ScrollIntoView(rowContainer, this.Columns[column]);

                    cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
                }

                return cell;
            }

            return null;
        }

        #endregion GetCell

        #region GetRow

        /// <summary>
        /// Gets the DataGridRow based on the given index
        /// </summary>
        /// <param name="index">the index of the container to get</param>
        public DataGridRow GetRow(int index)
        {
            DataGridRow row = (DataGridRow)this.ItemContainerGenerator.ContainerFromIndex(index);
            if (row == null)
            {
                // may be virtualized, bring into view and try again
                this.ScrollIntoView(this.Items[index]);

                row = (DataGridRow)this.ItemContainerGenerator.ContainerFromIndex(index);
            }

            return row;
        }

        #endregion GetRow


        #region TextBox更新时更新数据源


        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            var txt = sender as System.Windows.Controls.TextBox;
            if (txt.GetBindingExpression(System.Windows.Controls.TextBox.TextProperty) != null)
            {
                txt.GetBindingExpression(System.Windows.Controls.TextBox.TextProperty).UpdateSource();
            }
        }

        public event RoutedEventHandler TextBoxSelectionChangedEvent;

        public void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
        {
            if (TextBoxSelectionChangedEvent != null)
            {
                TextBoxSelectionChangedEvent(sender, e);
            }
        }

        public event KeyEventHandler TextBox_PreviewKeyDownEvent;

        public void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (TextBox_PreviewKeyDownEvent != null)
            {
                TextBox_PreviewKeyDownEvent(sender, e);
            }
        }

        public event MouseButtonEventHandler TextBox_PreviewMouseDoubleClickEvent;

        public void TextBox_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (TextBox_PreviewMouseDoubleClickEvent != null)
            {
                TextBox_PreviewMouseDoubleClickEvent(sender, e);
            }
        }

        #endregion

        #region CheckBox更新时更新数据源

        private void CheckBox_Clicked(object sender, RoutedEventArgs e)
        {
            var chk = sender as System.Windows.Controls.CheckBox;
            chk.GetBindingExpression(System.Windows.Controls.CheckBox.IsCheckedProperty).UpdateSource();
        }

        #endregion

        #region 内容选择值(1,2,3)

        public string[] GetSelectedValues(string path)
        {
            if (!path.Contains("Element"))
            {
                throw new Exception("CustomDateGrid.ConcatSelectedValues尚不支持非XElement数据源操作");
            }
            if (!path.EndsWith(".Value"))
            {
                throw new Exception("CustomDateGrid.ConcatSelectedValues参数Path必须是以节点值.Value结尾");
            }
            if (this.SelectedItems.Count == 0)
            {
                return new string[] { };
            }
            string[] elementNames = path.Split(new string[] { "Element[", "].Element[", "].Value" }, StringSplitOptions.RemoveEmptyEntries);//多层节点名称集合
            Func<XElement, string> selectValue = (XElement xe) =>
            {
                XElement xeFinalLevel = xe;//最后一层节点
                foreach (string elementName in elementNames)
                {
                    xeFinalLevel = xeFinalLevel.Element(elementName);
                }
                return xeFinalLevel.Value;
            };
            return this.SelectedItems.OfType<XElement>().Select(selectValue).ToArray();
        }

        public string ConcatSelectedValues(string path, string format = "{0}")
        {
            if (!path.Contains("Element"))
            {
                throw new Exception("CustomDateGrid.ConcatSelectedValues尚不支持非XElement数据源操作");
            }
            if (!path.EndsWith(".Value"))
            {
                throw new Exception("CustomDateGrid.ConcatSelectedValues参数Path必须是以节点值.Value结尾");
            }
            if (this.SelectedItems.Count == 0)
            {
                return "";
            }
            string[] elementNames = path.Split(new string[] { "Element[", "].Element[", "].Value" }, StringSplitOptions.RemoveEmptyEntries);//多层节点名称集合
            Func<XElement, string> selectValue = (XElement xe) =>
            {
                XElement xeFinalLevel = xe;//最后一层节点
                foreach (string elementName in elementNames)
                {
                    xeFinalLevel = xeFinalLevel.Element(elementName);
                }
                return string.Format(format, xeFinalLevel.Value);
            };
            return this.SelectedItems.OfType<XElement>().Select(selectValue).Aggregate((x, y) => x + "," + y);
        }
        #endregion

        ///// <summary>
        ///// 从第一页翻到最后一页， 该委托参数负责处理每页数据源
        ///// </summary>
        ///// <param name="act"></param>
        ///// <returns></returns>
        //public Action<Action<XElement[]>> LeafThrough;

        /// <summary>
        /// 从所有页中获取条目
        /// </summary>
        public Func<XElement[]> GetItemsFromAllPages;

        public void ExportExcel(List<XElement> itemList, string[] columns, string savePath = "")
        {
            ExportExcel(itemList, columns, @"", -1, null, false, savePath);
        }

        /// <summary>
        /// 导出EXECL
        /// </summary>
        /// <param name="itemList">数据源</param>
        /// <param name="columns">需要导出的表头列集合, 对应DataGrid的列头标题</param>
        /// <param name="templatePath">模板文件路径</param>
        /// <param name="dataRangeStartRowIndex">导出数据开始行索引</param>
        public void ExportExcel(List<XElement> itemList, string[] columns, string templatePath, int dataRangeStartRowIndex, Dictionary<string, object> replacementDic, bool printOrShow, string savePath = "")
        {
            Microsoft.Office.Interop.Excel.Application app;
            try
            {
                app = (Microsoft.Office.Interop.Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
            }
            catch
            {
                app = new Microsoft.Office.Interop.Excel.ApplicationClass().Application;
            }
            Microsoft.Office.Interop.Excel.Workbooks workbooks = app.Workbooks;
            Microsoft.Office.Interop.Excel.Workbook workbook;
            if (templatePath == "")
            {
                workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
            }
            else
            {
                workbook = workbooks.Add(templatePath);
            }
            try
            {
                Microsoft.Office.Interop.Excel.Sheets worksheets = workbook.Worksheets;
                Microsoft.Office.Interop.Excel.Worksheet sheet = (Microsoft.Office.Interop.Excel.Worksheet)worksheets.get_Item(1);

                if (replacementDic != null)
                {
                    foreach (var rplc in replacementDic)
                    {
                        foreach (Microsoft.Office.Interop.Excel.Name n in workbook.Names)
                        {
                            if (n.Name == rplc.Key)
                            {
                                n.RefersToRange.Value2 = rplc.Value;
                                break;
                            }
                        }
                    }
                }
                Microsoft.Office.Interop.Excel.Range range;

                if (templatePath == "")
                {
                    //app.Cells.Select();
                    app.Cells.RowHeight = 30;
                    app.Cells.Font.Size = 10;
                    app.Cells.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;

                }
                if (dataRangeStartRowIndex == -1)
                {
                    #region 设置标题

                    range = app.Range[sheet.Cells[1, 1], sheet.Cells[1, columns.Length]];
                    range.Borders.LineStyle = 1;
                    range.Font.Name = "宋体";
                    range.Font.Size = 16;
                    range.Font.Bold = true;
                    range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
                    //range.ColumnWidth = 18;
                    range.Select();
                    range.EntireColumn.AutoFit();

                    for (var c = 1; c <= columns.Length; c++)
                    {
                        sheet.Cells[1, c] = columns[c - 1];
                        range = app.Range[sheet.Cells[1, c], sheet.Cells[1, c]];
                        //根据datagrid中的列宽设定excel中的列宽
                        //由于存在隐藏列， 这里不能用列索引解决
                        var col = this.Columns.OfType<DataGridColumn>().FirstOrDefault(x => x.Header.ToString() == columns[c - 1]);
                        range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
                        range.Font.Name = "宋体";
                        range.Font.Size = 13;
                        if (col.ActualWidth <= 1000)
                            range.ColumnWidth = col.ActualWidth / 6; //经实际观察, 除以6比较合适


                        Binding bd = null;
                        if (col is DataGridBoundColumn)
                        {
                            bd = (col as DataGridBoundColumn).Binding as Binding;
                        }
                        else
                        {
                            bd = col.ClipboardContentBinding as Binding;
                        }
                        string[] parts = bd.Path.Path.Split(new string[] { "Element[", "].Value" }, StringSplitOptions.RemoveEmptyEntries);
                        string columName = "";
                        if (parts.Length >= 1)
                        {
                            columName = parts[parts.Length - 1];
                        }
                        if (SysParam.ExcelNumberFormatLocal == 0)//0：全部为字符；1：根据内容自动适应类型
                        {
                            //如果存在converter的话，可能是货币或日期格式，需要涉及到计算
                            if ((SysParam.ExcelNumber != null && SysParam.ExcelNumber.Contains(columName)) || (bd.ConverterParameter != null && string.Format("{0}", bd.ConverterParameter) == "Money"))
                            {
                                //range = app.Range[sheet.Cells[2, c], sheet.Cells[itemList.Count + 1, c]];
                                //range.Style = "Currency";
                            }
                            else
                            {
                                range = app.Range[sheet.Cells[2, c], sheet.Cells[itemList.Count + 1, c]];
                                range.Cells.NumberFormat = "@";
                            }
                        }
                        else
                        {
                            if (SysParam.ExcelNumber != null && SysParam.ExcelNumber.Contains(columName))
                            {
                                range = app.Range[sheet.Cells[2, c], sheet.Cells[itemList.Count + 1, c]];
                                range.Cells.NumberFormat = "@";
                            }
                        }
                    }
                    #endregion
                }

                int currentRowIndex = dataRangeStartRowIndex == -1 ? 2 : dataRangeStartRowIndex;//从第二行开始
                object[,] objValArray = new object[itemList.Count, columns.Length];
                for (var r = 0; r < itemList.Count; r++)
                {
                    for (var c = 1; c <= columns.Length; c++)
                    {
                        //由于存在隐藏列， 这里不能用列索引解决
                        var col = this.Columns.OfType<DataGridColumn>().FirstOrDefault(x => x.Header.ToString() == columns[c - 1]);
                        if (col == null)
                        {
                            objValArray[r, c - 1] = itemList[r].Element(columns[c - 1]).GetValue();
                        }
                        else
                        {
                            Binding bd = null;
                            if (col is DataGridBoundColumn)
                            {
                                bd = (col as DataGridBoundColumn).Binding as Binding;
                            }
                            else
                            {
                                bd = col.ClipboardContentBinding as Binding;
                            }
                            string[] pathSplitted = bd.Path.Path.Split(XElementExtensions.SeperatorArray, StringSplitOptions.RemoveEmptyEntries);
                            string value = pathSplitted.Length == 0 ? "" : itemList[r].Element(pathSplitted[0]).GetValue();

                            if (bd.Converter == null || string.Format("{0}", bd.ConverterParameter) == "Money")//是否需要转化
                            {
                                objValArray[r, c - 1] = value;
                            }
                            else
                            {
                                objValArray[r, c - 1] = bd.Converter.Convert(value, null, bd.ConverterParameter, null);
                            }
                        }
                    }
                    currentRowIndex++;
                }

                range = app.Range[sheet.Cells[currentRowIndex - itemList.Count, 1], sheet.Cells[currentRowIndex - 1, columns.Length]];
                if (templatePath == "")
                {
                    range.Borders.LineStyle = 1;
                    range.Font.Name = "宋体";
                    range.Font.Size = 12;
                    range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignLeft;
                }
                range.Value2 = objValArray;
                if (savePath != "")
                {
                    workbook.SaveCopyAs(savePath);
                }
                else
                {
                    if (printOrShow)
                    {
                        sheet.PrintOutEx();
                        object saveChanges = false;
                        workbook.Close(saveChanges);
                    }
                    else
                    {
                        app.Visible = true;  //打开Excel
                    }
                }
            }
            catch
            {
                object saveChanges = false;
                workbook.Close(saveChanges);
            }
        }

        public void ExportWord(List<XElement> itemList, string[] columns, string savePath = "")
        {
            //建立Word对象
            Microsoft.Office.Interop.Word.Application app;
            try
            {
                app = (Microsoft.Office.Interop.Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
            }
            catch
            {
                app = new Microsoft.Office.Interop.Word.ApplicationClass().Application;
            }
            Object myobj = System.Reflection.Missing.Value;

            Microsoft.Office.Interop.Word.Table mytable;//声明Word表格
            Microsoft.Office.Interop.Word.Selection mysel;//声明Word选区

            object defaultTableBehavior = Microsoft.Office.Interop.Word.WdDefaultTableBehavior.wdWord9TableBehavior;
            object autoFitBehavior = Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitFixed;

            Microsoft.Office.Interop.Word.Document mydoc = app.Documents.Add(ref myobj, ref myobj, ref myobj, ref myobj);
            mydoc.PageSetup.Orientation = Microsoft.Office.Interop.Word.WdOrientation.wdOrientLandscape;  //设置纸张为纵向
            float pageWidth = (float)this.Columns.Sum(x => x.Width.Value);
            if (pageWidth > 300)
                mydoc.PageSetup.PageWidth = pageWidth > 1584 ? 1584 : pageWidth;

            mydoc.Select();
            mysel = app.Selection;
            //将数据生成Word表格文件
            //mytable = mydoc.Tables.Add(mysel.Range, ExportTotalNum + 1, this.Columns.Count, ref myobj, ref myobj);  //无框表格
            mytable = mydoc.Tables.Add(mysel.Range, itemList.Count + 1, this.Columns.Count, ref defaultTableBehavior, ref autoFitBehavior);
            //设置列宽
            //mytable.Columns.SetWidth(80, Microsoft.Office.Interop.Word.WdRulerStyle.wdAdjustNone);
            //mytable.PreferredWidthType = Microsoft.Office.Interop.Word.WdPreferredWidthType.wdPreferredWidthPoints;
            //mytable.PreferredWidth = 97.5f;  //不能设置成100%，因为word默认的单元格间距使宽度大于页面宽度

            //输出列标题数据
            for (int i = 0; i < this.Columns.Count; i++)
            {
                try
                {
                    mytable.Columns[i + 1].Width = (float)this.Columns[i].Width.Value; //设置列宽等于列表列宽
                }
                catch { }
                mytable.Cell(1, i + 1).Range.InsertAfter(this.Columns[i].Header.ToString());
            }
            mytable.Rows[1].Range.Bold = 2;

            int currentRowIndex = 2;//从第二行开始

            mytable.Cell(2, 1).Select();

            for (int r = 0; r < itemList.Count; r++)
            {
                for (var c = 1; c <= columns.Length; c++)
                {
                    //由于存在隐藏列， 这里不能用列索引解决
                    var col = this.Columns.OfType<DataGridColumn>().FirstOrDefault(x => x.Header.ToString() == columns[c - 1]);
                    Binding bd = null;
                    if (col is DataGridBoundColumn)
                    {
                        bd = (col as DataGridBoundColumn).Binding as Binding;
                    }
                    else
                    {
                        bd = col.ClipboardContentBinding as Binding;
                    }
                    string[] pathSplitted = bd.Path.Path.Split(XElementExtensions.SeperatorArray, StringSplitOptions.RemoveEmptyEntries);
                    string value = pathSplitted.Length == 0 ? "" : itemList[r].Element(pathSplitted[0]).GetValue();

                    if (bd.Converter == null)//是否需要转化
                    {
                        app.Selection.TypeText(value);
                    }
                    else
                    {
                        app.Selection.TypeText(bd.Converter.Convert(value, null, bd.ConverterParameter, null).ToString());
                    }
                    if (c < columns.Length || r < itemList.Count - 1)
                    {
                        object missing = System.Reflection.Missing.Value;
                        object direction;
                        direction = Microsoft.Office.Interop.Word.WdUnits.wdCell;
                        app.Selection.MoveRight(ref direction, ref missing, ref missing);
                    }
                }

                currentRowIndex++;//当前的行索引
            }
            app.Visible = true;
        }

        /// <summary>
        /// 获取列表中显示的节点名称
        /// </summary>
        public string[] GetColumns()
        {
            return this.Columns.OfType<DataGridColumn>().Where(x => (x is DataGridBoundColumn || (x is DataGridTemplateColumn && (x as DataGridTemplateColumn).ClipboardContentBinding != null))
                        && x.Header != null && x.Visibility == System.Windows.Visibility.Visible).OrderBy(x => x.DisplayIndex).Select(x => x.Header.ToString()).ToArray();
        }

        public void Export(Action<List<XElement>, string[], string> exportExternalFile, bool exportCurrentPage, string[] columns = null, string savePath = "")
        {
            LoadingWaitingFor loadingWaitingFor = new LoadingWaitingFor("正在生成，请稍后......");
            try
            {
                loadingWaitingFor.Topmost = true;
                loadingWaitingFor.Show();    //跳出等待窗口

                if (columns == null)
                {
                    columns = GetColumns();
                }
                List<XElement> itemList = new List<XElement>();
                if (exportCurrentPage || GetItemsFromAllPages == null)
                {
                    itemList = this.Items.OfType<XElement>().ToList();
                }
                else
                {
                    if (this.AsTreeView)
                    {
                        itemList = RowXElementHelper.GetFlattenedTreeViewItems(GetItemsFromAllPages()).OfType<XElement>().ToList();
                    }
                    else
                    {
                        itemList = GetItemsFromAllPages().ToList();
                    }
                }
                exportExternalFile(itemList, columns, savePath);
            }
            catch (Exception ex)
            {
                loadingWaitingFor.Close();
                System.Windows.MessageBox.Show("导出数据失败，原因：" + ex.GetFullMessage(), "系统提示");
            }
            finally
            {
                if (loadingWaitingFor != null)
                    loadingWaitingFor.Close();
            }
        }



        #region 属性

        public static readonly DependencyProperty AsTreeViewProperty = DependencyProperty.Register("AsTreeView", typeof(bool), typeof(CustomDataGrid)
            , new PropertyMetadata(false, OnAsTreeViewChanged));
        public bool AsTreeView
        {
            get { return (bool)GetValue(AsTreeViewProperty); }
            set
            {
                SetValue(AsTreeViewProperty, value);
            }
        }

        private static void OnAsTreeViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue)
            {
                CustomDataGrid dg = d as CustomDataGrid;
                dg.RowStyle = new Style(typeof(DataGridRow));
                var trig = new DataTrigger() { Binding = new Binding("IsVisible"), Value = false };
                dg.RowStyle.Triggers.Add(trig);
                trig.Setters.Add(new Setter(DataGridRow.VisibilityProperty, Visibility.Collapsed));

                dg.CanUserSortColumns = false;
            }
        }

        private bool _treeNodeExpandable = true;
        public bool TreeNodeExpandable
        {
            get { return _treeNodeExpandable; }
            set
            {
                _treeNodeExpandable = value;
                if (!_treeNodeExpandable)
                {
                    foreach (RowXElement rx in this.Items.OfType<RowXElement>().Where(x => x.RowChildren != null))
                    {
                        rx.IsExpanded = false;
                    }
                }
            }
        }


        public static readonly DependencyProperty DefaultSelectedRowIndexProperty = DependencyProperty.Register("DefaultSelectedRowIndex", typeof(int), typeof(CustomDataGrid)
            , new PropertyMetadata(SysParam.DataGridDefaultSelectedRowIndex));
        public int DefaultSelectedRowIndex
        {
            get { return (int)GetValue(DefaultSelectedRowIndexProperty); }
            set { SetValue(DefaultSelectedRowIndexProperty, value); }
        }


        /// <summary>
        /// 面板Code
        /// </summary>
        public static readonly DependencyProperty UIPartCodeProperty = DependencyProperty.Register("UIPartCode", typeof(string), typeof(CustomDataGrid), new PropertyMetadata("", new PropertyChangedCallback(OnUIPartCodeProperyChanged)));
        public string UIPartCode
        {
            get { return GetValue(UIPartCodeProperty).ToString(); }
            set { SetValue(UIPartCodeProperty, value); }
        }
        private static void OnUIPartCodeProperyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //CustomDataGrid cdg = d as CustomDataGrid;
        }

        /// <summary>
        /// 是否能自定义
        /// </summary>
        public static readonly DependencyProperty IsCanCustomProperty = DependencyProperty.Register("IsCanCustom", typeof(bool), typeof(CustomDataGrid), new PropertyMetadata(false, new PropertyChangedCallback(OnIsCanCustomProperyChanged)));
        public bool IsCanCustom
        {
            get { return Convert.ToBoolean(GetValue(IsCanCustomProperty)); }
            set { SetValue(IsCanCustomProperty, value); }
        }
        private static void OnIsCanCustomProperyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //CustomDataGrid cdg = d as CustomDataGrid;
        }

        /// <summary>
        /// 导出设置
        /// </summary>
        public static readonly DependencyProperty ExportIsVisibleProperty = DependencyProperty.Register("ExportIsVisible", typeof(bool), typeof(CustomDataGrid), new PropertyMetadata(true, new PropertyChangedCallback(OnExportIsVisibleChanged)));
        public bool ExportIsVisible
        {
            get { return Convert.ToBoolean(GetValue(ExportIsVisibleProperty)); }
            set { SetValue(ExportIsVisibleProperty, value); }
        }
        private static void OnExportIsVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //CustomDataGrid cdg = d as CustomDataGrid;
        }

        #endregion


        #region 查询全局定义UIDataGrid列
        /// <summary>
        /// 查询全局定义UIDataGrid列根据 UIPartCode
        /// </summary>
        /// <returns></returns>
        private List<XElement> GetGridColumns()
        {
            List<XElement> tempColumnList = new List<XElement>();  //全局定义UI列表列
            try
            {
                using (HttpResponseMessage res = "GridColumns/GetMultiple".HttpPost(new XElement("UIPartCode", this.UIPartCode)))
                {
                    ProcessRequest.Process(res, (ResponseMessageInfo resInfo) =>
                    {
                        tempColumnList = resInfo.ResponseDataMainBody.Elements().ToList();
                    });
                }
            }
            catch (Exception ex)
            {
                ErrorInfo er = new ErrorInfo("查询DataGrid列失败：", ex.Message);
                er.Show();
            }
            return tempColumnList;
        }
        #endregion
        #region 查询自定义UIDataGrid列
        /// <summary>
        /// 查询自定义UIDataGrid列
        /// </summary>
        /// <returns></returns>
        private List<XElement> GetCustomGridColumns()
        {
            List<XElement> tempColumnList = new List<XElement>();  //自定义UI列表列
            try
            {
                //using (HttpResponseMessage res = "CustomGridColumns/GetMultiple".HttpPost(
                //    new XElement("UIPartCode", this.UIPartCode),
                //    new XElement("UserID", Login.UserLogin.CurrentUser.UserID)))
                //{
                //    ProcessRequest.Process(res, (ResponseMessageInfo resInfo) =>
                //    {
                //        tempColumnList = resInfo.ResponseDataMainBody.Elements().ToList();
                //    });
                //}
            }
            catch (Exception ex)
            {
                ErrorInfo er = new ErrorInfo("查询DataGrid自定义列失败：", ex.Message);
                er.Show();
            }
            return tempColumnList;
        }
        #endregion


        #region 获取绑定列的XElement集合
        /// <summary>
        /// 获取绑定列的XElement集合
        /// </summary>
        public XElement[] BindingElements
        {
            get
            {
                List<Binding> bindingList = new List<Binding>(); //控件的绑定列表
                List<string> bingingXElementNameList = new List<string>(); //指定的绑定XElement名称
                foreach (DataGridColumn c in this.Columns.OfType<DataGridColumn>())
                {
                    if (c is DataGridTemplateColumn)
                    {
                        var cellTemplate = (c as DataGridTemplateColumn).CellTemplate;
                        cellTemplate.Seal(); //如果不调用这个方法，下面的语句会爆出FrameworkElementFactory must be in a sealed template for this operation.
                        var content = cellTemplate.LoadContent();
                        if (content is DatePicker)
                        {
                            bindingList.Add((content as DatePicker).GetBindingExpression(DatePicker.TextProperty).ParentBinding);
                        }
                        else if (content is TextBox)
                        {
                            bindingList.Add((content as TextBox).GetBindingExpression(TextBox.TextProperty).ParentBinding);
                        }
                        else if (content is CheckBox)
                        {
                            bindingList.Add((content as CheckBox).GetBindingExpression(CheckBox.IsCheckedProperty).ParentBinding);
                        }
                        else if (content is UComboBox)
                        {
                            bindingList.Add((content as UComboBox).GetBindingExpression(UComboBox.SelectedValue1Property).ParentBinding);
                            bindingList.Add((content as UComboBox).GetBindingExpression(UComboBox.SelectedValue2Property).ParentBinding);
                        }
                        else if (content is ComboBox)
                        {
                            var cob = content as ComboBox;
                            if (cob.IsEditable)
                            {
                                bindingList.Add(cob.GetBindingExpression(ComboBox.TextProperty).ParentBinding);
                            }
                            else
                            {
                                bindingList.Add(cob.GetBindingExpression(ComboBox.SelectedValueProperty).ParentBinding);
                            }
                        }
                        else if (content is Twi.COMMON.WPF.CtlExtended.DateTimePicker)
                        {
                            var cob = content as Twi.COMMON.WPF.CtlExtended.DateTimePicker;
                            bindingList.Add((content as Twi.COMMON.WPF.CtlExtended.DateTimePicker).GetBindingExpression(Twi.COMMON.WPF.CtlExtended.DateTimePicker.TextProperty).ParentBinding);
                        }
                        else if (content is IChildElement) //是否继承IChildElement接口
                        {
                            foreach (var x in (content as IChildElement).GetBindingExpression())
                            {
                                if (x != null)
                                {
                                    bindingList.Add(x.ParentBinding);
                                }
                            }

                            foreach (var x in (content as IChildElement).GetBindingXElementName())
                            {
                                bingingXElementNameList.Add(x);
                            }
                        }
                    }
                    else if (c is DataGridBoundColumn)
                    {
                        bindingList.Add((c as DataGridBoundColumn).Binding as Binding);
                    }
                }
                List<XElement> elementList = new List<XElement>();
                foreach (var b in bindingList)
                {
                    foreach (var elementName in b.Path.Path.Split(XElementExtensions.SeperatorArray, StringSplitOptions.RemoveEmptyEntries))
                    {
                        if (elementList.FirstOrDefault(x => x.Name.LocalName == elementName) == null)
                        {
                            elementList.Add(new XElement(elementName));
                        }
                    }
                }
                foreach (var b in bingingXElementNameList)
                {
                    if (elementList.FirstOrDefault(x => x.Name.LocalName == b) == null)
                    {
                        elementList.Add(new XElement(b));
                    }
                }
                return elementList.ToArray();
            }
        }
        #endregion
        #region 在列表可编辑的状态下添加条目
        /// <summary>
        /// 在列表可编辑的状态下添加条目
        /// </summary>
        /// <param name="items"></param>
        public void AddEditableItems(params XElement[] items)
        {
            try
            {
                if (items == null || items.Length == 0)
                {
                    return;
                }
                if (this.ItemsSource == null)
                {
                    this.ItemsSource = items;
                }
                else
                {
                    List<XElement> xelementList = (this.ItemsSource as XElement[]).ToList();
                    foreach (var x in items)
                    {
                        xelementList.Add(x);
                    }
                    this.ItemsSource = xelementList.ToArray();
                }
            }
            catch
            {
                MessageBox.Show("添加失败！");
            }
        }
        #endregion
        #region 在列表可编辑的状态下移除条目
        /// <summary>
        /// 在列表可编辑的状态下移除条目
        /// </summary>
        /// <param name="items"></param>
        public void RemoveItems(params XElement[] items)
        {
            try
            {
                if (items == null || items.Length == 0 || this.ItemsSource == null)
                {
                    return;
                }
                List<XElement> xelementList = (this.ItemsSource as XElement[]).ToList();
                foreach (var x in items)
                {
                    xelementList.Remove(x);
                }
                this.ItemsSource = xelementList.ToArray();
            }
            catch
            {
                MessageBox.Show("删除失败！");
            }
        }
        #endregion

        /// <summary>
        /// DataGrid回车事件处理
        /// </summary>
        /// <param name="e"></param>
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            switch (e.Key)
            {
                case Key.Enter:
                    //获焦点
                    if (this.CurrentCell.Column is DataGridTemplateColumn)
                    {
                        GKeyboard.Press(Key.Tab);
                    }
                    //if (e.OriginalSource is ComboBox)
                    //{
                    //    GKeyboard.Press(Key.Tab);
                    //}
                    //else if (e.OriginalSource is DataGridCell && ((DataGridCell)e.OriginalSource).Column is DataGridTemplateColumn)
                    //{
                    //    GKeyboard.Press(Key.Tab);
                    //}
                    break;
            }
        }


        #region 滚动条分页

        /// <summary>
        /// 滚动条分页
        /// </summary>
        public bool ScrollbarPaging
        {
            get { return Convert.ToBoolean(GetValue(ScrollbarPagingProperty)); }
            set
            {
                SetValue(ScrollbarPagingProperty, value);

            }
        }
        public static readonly DependencyProperty ScrollbarPagingProperty = DependencyProperty.Register("ScrollbarPaging", typeof(bool), typeof(CustomDataGrid));

        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);

            if (this.ScrollbarPaging) //添加滚动条滚动事件
            {
                var scrollViewer = this.GetVisualChild<ScrollViewer>(this);
                scrollViewer.ScrollChanged += new ScrollChangedEventHandler(scrollViewer_ScrollChanged);
            }
        }

        void scrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            if (e.VerticalChange > 0 && (e.ExtentHeight - e.ViewportHeight - e.VerticalOffset) < 5 && ScrollPageIndex < (ScrollPageAmount - 1))
            {
                AddItems();
            }
        }

        /// <summary>
        /// 增加条目
        /// </summary>
        public void AddItems()
        {
            ScrollPageIndex += 1;
            var msgInfo = Retrieve();
            if (msgInfo == null) return;
            foreach (XElement xeItem in msgInfo.ResponseDataMainBody.Elements())
                this.Items.Add(xeItem);
        }

        /// <summary>
        /// 刷新
        /// </summary>
        public void RefreshItems()
        {

            var scrollViewer = this.GetVisualChild<ScrollViewer>(this);
            if (scrollViewer != null)
            {
                scrollViewer.ScrollToVerticalOffset(0);
            }

            ScrollPageIndex = 0;

            this.Items.Clear();
            var msgInfo = Retrieve();
            if (msgInfo == null)
            {
                return;
            }
            ScrollPageAmount = msgInfo.PageAmount;
            if (ScrollPageAmount > 0)
            {
                foreach (XElement xeItem in msgInfo.ResponseDataMainBody.Elements())
                    this.Items.Add(xeItem);
            }

        }

        public int ScrollPageSize { get; set; }

        public int ScrollPageIndex { get; set; }

        public int ScrollPageAmount { get; set; }

        /// <summary>
        /// 绑定数据： return-数据包（包含分页信息）
        /// </summary>
        public Func<ResponseMessageInfo> Retrieve;


        #endregion


        private bool GetMouseTargetRow(Visual theTarget, GetPosition position)
        {
            Rect rect = VisualTreeHelper.GetDescendantBounds(theTarget);
            Point point = position((IInputElement)theTarget);
            return rect.Contains(point);
        }

        public delegate Point GetPosition(IInputElement element);


        public int GetCurrentRowIndex(GetPosition pos)
        {
            int curIndex = -1;
            for (int i = 0; i < this.Items.Count; i++)
            {
                DataGridRow itm = GetRow(i);
                if (GetMouseTargetRow(itm, pos))
                {
                    curIndex = i;
                    break;
                }
            }
            return curIndex;
        }

        /// <summary>
        /// 获取指定坐标的行绑定的数据源的SortOrder值
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        public XElement GetCurrentRowDataItem(GetPosition pos)
        {
            for (int i = 0; i < this.Items.Count; i++)
            {
                DataGridRow row = GetRow(i);
                if (GetMouseTargetRow(row, pos))
                {
                    return row.DataContext as XElement;
                }
            }
            return null;
        }

        public Tuple<int, int> GetCurrentRowIndexAndSortOrder(GetPosition pos)
        {
            int curIndex = -1;
            int sortOrder = -1;
            for (int i = 0; i < this.Items.Count; i++)
            {
                DataGridRow itm = GetRow(i);
                if (GetMouseTargetRow(itm, pos))
                {
                    curIndex = i;
                    sortOrder = int.Parse((itm.DataContext as XElement).Element("SortOrder").Value);
                    break;
                }
            }
            return new Tuple<int, int>(curIndex, sortOrder);
        }

        public bool SuppressSelectionChangdEvent = false;

        protected override void OnSelectionChanged(SelectionChangedEventArgs e)
        {
            if (!(e.OriginalSource is CustomDataGrid)) { return; }

            if (SuppressSelectionChangdEvent)
            {
                e.Handled = true;
            }
            else
            {
                if (KeepPreviousSelection)
                {
                    if (this.SelectedItem != null)
                    {
                        if (e.AddedItems.Count > 0 || e.RemovedItems.Count > 1)
                        {
                            this.SuppressSelectionChangdEvent = true;
                            foreach (var i in e.RemovedItems)
                            {
                                DataGridRow z = this.ItemContainerGenerator.ContainerFromItem(i) as DataGridRow;
                                if (z == null)
                                {
                                    this.ScrollIntoView(i);
                                    z = this.ItemContainerGenerator.ContainerFromItem(i) as DataGridRow;
                                }
                                z.IsSelected = true;
                            }
                            this.ScrollIntoView(this.SelectedItem);
                            this.SuppressSelectionChangdEvent = false;
                        }
                    }
                }

                if (AsTreeView && TreeNodeExpandable && SelectionMode == DataGridSelectionMode.Extended)
                {
                    this.SuppressSelectionChangdEvent = true;
                    foreach (RowXElement rx in e.RemovedItems)
                    {
                        if (rx.RowChildren != null)
                        {
                            var flattened = rx.GetFlattenedChildren();

                            foreach (RowXElement srx in this.SelectedItems.OfType<RowXElement>().ToArray())
                            {
                                if (flattened.Contains(srx))
                                {
                                    this.SelectedItems.Remove(srx);
                                }
                            }
                        }
                    }

                    foreach (RowXElement rx in e.AddedItems)
                    {
                        if (rx.RowChildren != null)
                        {
                            var flattened = rx.GetFlattenedChildren();
                            foreach (RowXElement srx in flattened)
                            {
                                if (!this.SelectedItems.Contains(srx))
                                {
                                    this.SelectedItems.Add(srx);
                                }
                            }

                        }
                    }
                    this.SuppressSelectionChangdEvent = false;
                }

            }
            base.OnSelectionChanged(e);
        }

        protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            if (e.OriginalSource is Rectangle && this.Items.Count > 0)
            {
                if (this.Items.Count == this.SelectedItems.Count)
                {
                    this.SuppressSelectionChangdEvent = true;

                    var o = this.SelectedItem;

                    foreach (var i in this.Items)
                    {
                        DataGridRow z = this.ItemContainerGenerator.ContainerFromItem(i) as DataGridRow;
                        if (z == null)
                        {
                            this.ScrollIntoView(i);
                            z = this.ItemContainerGenerator.ContainerFromItem(i) as DataGridRow;
                        }
                        z.IsSelected = false;
                    }

                    this.ScrollIntoView(o);

                    this.SuppressSelectionChangdEvent = false;

                    e.Handled = true;
                }
            }
            base.OnPreviewMouseLeftButtonDown(e);
        }

        /// <summary>
        /// 多选模式下，不撤销先前的选项
        /// </summary>
        public static readonly DependencyProperty KeepPreviousSelectionProperty = DependencyProperty.Register("KeepPreviousSelection", typeof(bool), typeof(CustomDataGrid)
           , new PropertyMetadata(false, null));
        public bool KeepPreviousSelection
        {
            get { return (bool)GetValue(KeepPreviousSelectionProperty); }
            set { SetValue(KeepPreviousSelectionProperty, value); }
        }


        public void CollapseAll()
        {
            foreach (var x in this.Items.OfType<RowXElement>().Where(x => x.RowChildren != null && x.RowChildren.Count > 0))
            {
                x.IsExpanded = false;
            }
            this.Items.Refresh();

        }

        public void ExpandAll()
        {
            foreach (var x in this.Items.OfType<RowXElement>().Where(x => x.RowChildren != null && x.RowChildren.Count > 0))
            {
                x.IsExpanded = true;
            }
            this.Items.Refresh();
        }

    }


}
